﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Net.Mail;
using Microsoft.Win32;

namespace EdgeStatz.ESSystems.Objects
{
    public static class Weather
    {
        public static Conditions GetConditions(string location)
        {
            XmlDocument xmlGeoLookUp = new XmlDocument();
            XmlDocument xmlCurrentObj = new XmlDocument();

            xmlGeoLookUp.Load("http://api.wunderground.com/auto/wui/geo/GeoLookupXML/index.xml?query=" + location);

            Conditions current = new Conditions();
            current.City = xmlGeoLookUp.SelectSingleNode("location/city").InnerText;
            current.Country = xmlGeoLookUp.SelectSingleNode("location/country").InnerText;

            XmlNode stationNode = xmlGeoLookUp.SelectSingleNode("location/nearby_weather_stations/airport/station/icao");
            if (stationNode != null)
            {
                xmlCurrentObj.Load("http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=" + stationNode.InnerText);
            }
            else
            {
                int min_dist = int.MaxValue;
                string stationID = null;
                foreach (XmlNode node in xmlGeoLookUp.SelectNodes("location/nearby_weather_stations/pws"))
                {
                    try
                    {
                        int dist_km = Convert.ToInt32(node.SelectSingleNode("station/distance_km").InnerText);

                        if (dist_km < min_dist)
                        {
                            stationID = node.SelectSingleNode("station/id").InnerText;
                            min_dist = dist_km;
                        }
                    }
                    catch (Exception e) { }
                }
                if (stationID != null)
                    xmlCurrentObj.Load("http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?ID=" + stationID);
                else
                    return null;
            }
            if (xmlCurrentObj.SelectSingleNode("current_observation/station_id") != null &&
                xmlCurrentObj.SelectSingleNode("current_observation/station_id").InnerText != "")
            {
                current.Condition = xmlCurrentObj.SelectSingleNode("current_observation/weather").InnerText;
                current.TempC = xmlCurrentObj.SelectSingleNode("current_observation/temp_c").InnerText;
                current.TempF = xmlCurrentObj.SelectSingleNode("current_observation/temp_f").InnerText;
                current.Wind_Dir = xmlCurrentObj.SelectSingleNode("current_observation/wind_dir").InnerText;
                current.Wind_Mph = xmlCurrentObj.SelectSingleNode("current_observation/wind_mph").InnerText;

                foreach (XmlNode node in xmlCurrentObj.SelectNodes("current_observation/icons/icon_set"))
                {
                    if (node.Attributes["name"].Value.ToUpper().Equals("GENERIC"))
                    { current.Icon = node.SelectSingleNode("icon_url").InnerText; }
                }
            }
            return current;

            
        }
        public static Conditions[] GetForecast(string location)
        {
            List<Conditions> conditions = new List<Conditions> { };

            XmlDocument xmlForecast = new XmlDocument();
            xmlForecast.Load("http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=" + location);

            XmlDocument xmlGeoLookUp = new XmlDocument();
            xmlGeoLookUp.Load("http://api.wunderground.com/auto/wui/geo/GeoLookupXML/index.xml?query=" + location);

            string city = xmlGeoLookUp.SelectSingleNode("location/city").InnerText;
            string country = xmlGeoLookUp.SelectSingleNode("location/country").InnerText;

            foreach (XmlNode node in xmlForecast.SelectNodes("forecast/simpleforecast/forecastday"))
            {
                Conditions forecast = new Conditions();
                forecast.City = city;
                forecast.Country = country;
                forecast.DayOfWeek = node.SelectSingleNode("date/weekday").InnerText;
                forecast.High = node.SelectSingleNode("high/celsius").InnerText;
                forecast.Low = node.SelectSingleNode("low/celsius").InnerText;
                forecast.Condition = node.SelectSingleNode("conditions").InnerText;
                foreach (XmlNode node2 in node.SelectNodes("icons/icon_set"))
                {
                    if (node2.Attributes["name"].Value.ToUpper().Equals("GENERIC"))
                    { forecast.Icon = node2.SelectSingleNode("icon_url").InnerText; }
                }
                conditions.Add(forecast);
            }

            return conditions.ToArray();
        }
    }

    public class Conditions
    {
        string city = null;
        string country = null;
        string dayOfWeek = DateTime.Now.DayOfWeek.ToString();
        string condition = null;
        string tempF = null;
        string tempC = null;
        string humidity = null;
        string wind_dir = null;
        string wind_mph = null;
        string high = null;
        string low = null;
        string icon = null;

        public string City
        {
            get { return city; }
            set { city = value; }
        }

        public string Country
        {
            get { return country; }
            set { country = value; }
        }

        public string Icon
        {
            get { return icon; }
            set { icon = value; }
        }

        public string Condition
        {
            get { return condition; }
            set { condition = value; }
        }

        public string TempF
        {
            get { return tempF; }
            set { tempF = value; }
        }

        public string TempC
        {
            get { return tempC; }
            set { tempC = value; }
        }

        public string Humidity
        {
            get { return humidity; }
            set { humidity = value; }
        }

        public string Wind_Dir
        {
            get { return wind_dir; }
            set { wind_dir = value; }
        }

        public string Wind_Mph
        {
            get { return wind_mph; }
            set { wind_mph = value; }
        }

        public string DayOfWeek
        {
            get { return dayOfWeek; }
            set { dayOfWeek = value; }
        }

        public string High
        {
            get { return high; }
            set { high = value; }
        }

        public string Low
        {
            get { return low; }
            set { low = value; }
        }
    }

    public static class Email
    {
        private static EmailServer server;

        public static EmailServer Server
        {
            get { return server; }
            set
            {
                server = value;
            }
        }

        /// <summary>
        /// Sends an e-mail message using the designated SMTP mail server.
        /// </summary>
        /// <param name="subject">The subject of the message being sent.</param>
        /// <param name="messageBody">The message body.</param>
        /// <param name="toAddress">The recipient's e-mail address (separate multiple e-mail addresses
        /// with a semi-colon).</param>
        /// <param name="ccAddress">The address(es) to be CC'd (separate multiple e-mail addresses with
        /// a semi-colon).</param>
        /// <param name="BccAddress">The address(es) to be BCC'd (separate multiple e-mail addresses with
        /// a semi-colon).</param>
        /// <remarks>You must set the SMTP server within this method prior to calling.</remarks>
        /// <example>
        /// <code>
        ///   // Send a quick e-mail message
        ///   SendEmail.SendMessage("This is a Test", 
        ///                         "This is a test message...",
        ///                         "noboday@nowhere.com",
        ///                         "somebody@somewhere.com", 
        ///                         "ccme@somewhere.com");
        /// </code>
        /// </example>
        public static void SendMessage(string subject, string messageBody,
            string toAddress, string ccAddress, string bccAddress, string[] attachments)
        {
            MailMessage message = new MailMessage();
            SmtpClient client = new SmtpClient();

            // Set the sender's address
            message.From = new MailAddress(server.FromAddress);

            // Allow multiple "To" addresses to be separated by a semi-colon
            if (toAddress.Trim().Length > 0)
            {
                foreach (string addr in toAddress.Split(';'))
                {
                    message.To.Add(new MailAddress(addr));
                }
            }
            // Allow multiple "Cc" addresses to be separated by a semi-colon
            if (ccAddress.Trim().Length > 0)
            {
                foreach (string addr in ccAddress.Split(';'))
                {
                    message.CC.Add(new MailAddress(addr));
                }
            }
            // Allow multiple "Bcc" addresses to be separated by a semi-colon
            if (bccAddress.Trim().Length > 0)
            {
                foreach (string addr in bccAddress.Split(';'))
                {
                    message.Bcc.Add(new MailAddress(addr));
                }
            }

            // Set the subject and message body text
            message.Subject = subject;
            message.Body = messageBody;
            if (attachments != null)
                foreach (string fn in attachments)
                    if (!fn.Trim().Equals(""))
                        message.Attachments.Add(new Attachment(fn.Trim()));

            // TODO: *** Modify for your SMTP server ***
            // Set the SMTP server to be used to send the message
            if (server == null)
                throw new Exception("SMTP server cannot be null.");
            client.Host = server.Host;
            client.Port = server.Port;
            client.EnableSsl = server.EnableSsl;
            if (!server.UseDefaultCredentials)
                client.Credentials = new System.Net.NetworkCredential(server.AccountName, server.Password);
            else
                client.UseDefaultCredentials = true;

            // Send the e-mail message
            client.Send(message);
        }
    }

    public class EmailServer
    {
        private string host;
        private string userName;
        private string password;
        private bool useDefaultCred;
        private bool enableSsl;
        private string fromAddress;
        private int port;

        public string Host
        {
            get { return host; }
            set { host = value; }
        }
        public string AccountName
        {
            get { return userName; }
            set { userName = value; }
        }
        public string Password
        {
            get { return password; }
            set { password = value; }
        }
        public bool UseDefaultCredentials
        {
            get { return useDefaultCred; }
            set { useDefaultCred = value; }
        }
        public bool EnableSsl
        {
            get { return enableSsl; }
            set { enableSsl = value; }
        }
        public string FromAddress
        {
            get { return fromAddress; }
            set { fromAddress = value; }
        }
        public int Port
        {
            get { return port; }
            set { port = value; }
        }

        public EmailServer() { }
        public EmailServer(string host, int port, string fromAddress,
            bool useDefaultCred, bool enableSsl, string userName, string password)
        {
            this.host = host;
            this.port = port;
            this.fromAddress = fromAddress;
            this.userName = userName;
            this.password = password;
            this.useDefaultCred = useDefaultCred;
            this.enableSsl = enableSsl;
        }
    }
}
